package com.gopay.bis.manager.bank.bcdl;

import java.util.Date;
import java.util.Map;

import javax.annotation.Resource;

import com.gopay.common.domain.bank.abc.bcdl.quyeryCQRA10.req.ApReqCQRA10;
import com.gopay.common.domain.bank.abc.bcdl.quyeryCQRA10.req.ChannelReq;
import com.gopay.common.domain.bank.abc.bcdl.quyeryCQRA10.req.CmpReq;
import com.gopay.common.domain.bank.abc.bcdl.quyeryCQRA10.req.CorpReqAp;
import com.gopay.common.domain.bank.abc.bcdl.quyeryCQRA10.res.ApResCQRA10;
import org.apache.commons.lang.StringUtils;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.common.util.TransUtil;
import com.gopay.bis.common.util.constants.ConstantsABC;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.domain.bank.BcdlMessage;
import com.gopay.common.domain.bank.abc.bcdl.bal.req.ApQueryBalReq;
import com.gopay.common.domain.bank.abc.bcdl.bal.req.CmpQueryBalReq;
import com.gopay.common.domain.bank.abc.bcdl.bal.res.ApQueryBalRes;
import com.gopay.common.domain.bank.abc.bcdl.corp.req.ApCorpReq;
import com.gopay.common.domain.bank.abc.bcdl.corp.req.CmpCorpReq;
import com.gopay.common.domain.bank.abc.bcdl.corp.req.CorpReq;
import com.gopay.common.domain.bank.abc.bcdl.person.req.ApPersonReq;
import com.gopay.common.domain.bank.abc.bcdl.person.req.CmpPersonReq;
import com.gopay.common.domain.bank.abc.bcdl.person.req.CorpPersonReq;
import com.gopay.common.domain.bank.abc.bcdl.query.req.ApQueryReq;
import com.gopay.common.domain.bank.abc.bcdl.query.req.CmpQueryReq;
import com.gopay.common.domain.bank.abc.bcdl.query.res.ApQueryRes;
import com.gopay.common.domain.bank.abc.bcdl.res.NewApRes;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.DateUtils;
import com.gopay.remote.bank.businesses.BcdlService;

/**
 * 农行银企直连拼装对象
 * 
 * @AbcBcdlManager.java
 * @author lilili
 */
public class AbcBcdlManager {
	@Resource(name = "abcBcdlService")
	private BcdlService abcBcdlService;
	
	 @Resource(name = "abcConfig")
	 private Map<String, String> abcConfig;
	/**
     * 对公
     * 
     * @return
     */
    public NewApRes payCorp(BcdlMessage message)  throws GopayException{
        // 构建对公对象
        ApCorpReq ap = convertCorp(message);
        BankLogUtils.printBcdlEftManagerSendLog(ap);
        // 发送银行请求
        NewApRes res = (NewApRes) abcBcdlService.eft(ap);
        BankLogUtils.printBcdlEftManagerReturnLog(res);
        return res;
    }

    /**
     * 对私
     * 
     * @return
     */
    public NewApRes payPerson(BcdlMessage message)  throws GopayException{
        // 构建对私对象
        ApPersonReq ap = convertPerson(message);
        BankLogUtils.printBcdlEftManagerSendLog(ap);
        // 发送银行请求
        NewApRes res = (NewApRes) abcBcdlService.eft(ap);
        BankLogUtils.printBcdlEftManagerReturnLog(res);
        return res;
    }

    /**
     * 查询
     * 
     * @return
     */
    public ApQueryRes payQuery(BcdlMessage message)  throws GopayException{
        // 构建查询对象
        ApQueryReq ap = convertQuery(message);
        BankLogUtils.printBcdlManagerQuerySendLog(ap);
        // 发送银行
        ApQueryRes res = (ApQueryRes) abcBcdlService.eft(ap);
        BankLogUtils.printBcdlManagerQueryReturnLog(res);
        return res;
    }
    
    /**
     * 查询账户余额
     * 
     * @return
     */
    public ApQueryBalRes queryBal(BcdlMessage message)  throws GopayException{
        // 构建查询对象
        ApQueryBalReq ap = convertQueryBal(message);
        BankLogUtils.printBcdlManagerQueryBalanceSendLog(ap);
        // 发送银行
        ApQueryBalRes res = (ApQueryBalRes) abcBcdlService.eft(ap);
        res.setBalance(res.getAcc().getAvailBal());
        BankLogUtils.printBcdlManagerQueryBalanceReturnLog(res);
        res.setPayAccNum(abcConfig.get("ABC.BCDL.PAY.ACCOUNTNO"));
        return res;
    }
    
    /**
     * 构建查询账户余额对象
     * 
     * @param message
     * @return
     */
    private ApQueryBalReq convertQueryBal(BcdlMessage message) {
    	ApQueryBalReq ap = new ApQueryBalReq();
        CmpQueryBalReq cmp = new CmpQueryBalReq();
        ap.setBank(message.getBank());
        // 获取当前时间
        Date date = DateUtils.strToDate(DateUtils.getCurrDate());

        String reqSeqNo = message.getItemId() + DateUtils.getCurrDate("HHmmssSS");

        ap.setCcTransCode(abcConfig.get("ABC.BCDL.QUERY.BAL.TRANSCODE"));
        ap.setProductId(abcConfig.get("ABC.BCDL.PRODUCTID"));
        ap.setChannelType(abcConfig.get("ABC.BCDL.CHANNELTYPE"));
        ap.setCorpNo(abcConfig.get("ABC.BCDL.CORPNO"));
        ap.setOpNo(abcConfig.get("ABC.BCDL.OPNO"));
        ap.setAuthNo(" "); // 认证码
        ap.setReqSeqNo(reqSeqNo); // 请求方流水号
        ap.setReqDate(DateUtils.format(date, "yyyyMMdd"));
        ap.setReqTime(DateUtils.format(date, "HHmmss"));
        ap.setSign(" "); // 数字签名

        cmp.setDbProv(abcConfig.get("ABC.BCDL.PAY.ACCOUNTPROV"));
        cmp.setDbAccNo(abcConfig.get("ABC.BCDL.PAY.ACCOUNTNO"));
        cmp.setDbCur(ConstantsABC.ABC_ERP_CURTYPE_RMB);

        ap.setCmp(cmp);
        return ap;
    }

    /**
     * 构建查询对象
     * 
     * @param message
     * @return
     */
    private ApQueryReq convertQuery(BcdlMessage message) {
        ApQueryReq ap = new ApQueryReq();
        CmpQueryReq cmp = new CmpQueryReq();
        ap.setBank(message.getBank());
        // 获取当前时间
        Date date = DateUtils.strToDate(DateUtils.getCurrDate());

        String reqSeqNo = message.getItemId() + DateUtils.getCurrDate("HHmmssSS");

        ap.setCcTransCode(abcConfig.get("ABC.BCDL.QUERY.TRANSCODE"));
        ap.setProductId(abcConfig.get("ABC.BCDL.PRODUCTID"));
        ap.setChannelType(abcConfig.get("ABC.BCDL.CHANNELTYPE"));
        ap.setCorpNo(abcConfig.get("ABC.BCDL.CORPNO"));
        ap.setOpNo(abcConfig.get("ABC.BCDL.OPNO"));
        ap.setAuthNo(" "); // 认证码
        ap.setReqSeqNo(message.getOrderId()); // 请求方流水号
        ap.setReqDate(DateUtils.format(date, "yyyyMMdd"));
        ap.setReqTime(DateUtils.format(date, "HHmmss"));
        ap.setSign(" "); // 数字签名

        cmp.setDbProv(abcConfig.get("ABC.BCDL.PAY.ACCOUNTPROV"));
        cmp.setDbAccNo(abcConfig.get("ABC.BCDL.PAY.ACCOUNTNO"));
        cmp.setDbCur(ConstantsABC.ABC_ERP_CURTYPE_RMB);
        cmp.setCmeSeqNo(message.getOrderId());

        ap.setCmp(cmp);
        return ap;
    }

    /**
     * 构建对私对象
     * 
     * @param message
     * @return
     */
    private ApPersonReq convertPerson(BcdlMessage message) {
        ApPersonReq ap = new ApPersonReq();
        CmpPersonReq cmp = new CmpPersonReq();
        CorpPersonReq corp = new CorpPersonReq();
        ap.setBank(message.getBank());
        String transTime =TransUtil.getTransTime();
        Date orderDate = DateUtils.strToDate(transTime);

        ap.setCcTransCode(abcConfig.get("ABC.BCDL.PERSON.TRANSCODE"));
        ap.setProductId(abcConfig.get("ABC.BCDL.PRODUCTID"));
        ap.setChannelType(abcConfig.get("ABC.BCDL.CHANNELTYPE"));
        ap.setCorpNo(abcConfig.get("ABC.BCDL.CORPNO"));
        ap.setOpNo(abcConfig.get("ABC.BCDL.OPNO"));
        ap.setAuthNo(" "); // 认证码
        ap.setReqSeqNo(message.getGopayBankOrderNo());
        ap.setReqDate(DateUtils.format(orderDate, "yyyyMMdd"));
        ap.setReqTime(DateUtils.format(orderDate, "HHmmss"));
        ap.setSign(" "); // 数字签名
        ap.setAmt(message.getAmount().toString());

        cmp.setDbProv(abcConfig.get("ABC.BCDL.PAY.ACCOUNTPROV"));
        cmp.setDbAccNo(abcConfig.get("ABC.BCDL.PAY.ACCOUNTNO"));
        cmp.setDbLogAccNo(" "); // 借方逻辑账号
        cmp.setDbCur(ConstantsABC.ABC_ERP_CURTYPE_RMB);
        cmp.setCrProv(message.getRecvBankProvNo());
        cmp.setCrAccNo(message.getRecvBankAcctNum());
        cmp.setCrLogAccNo(" "); // 贷方逻辑账号
        cmp.setCrCur(ConstantsABC.ABC_ERP_CURTYPE_RMB);
        cmp.setConFlag(ConstantsABC.ABC_ERP_CONFLAG_TRUE);

        corp.setPsFlag(" ");
        corp.setBookingFlag(ConstantsABC.ABC_ERP_BOOKINGFLAG_FALSE); // 预约标志
        corp.setBookingDate(" "); // 预约日期
        corp.setBookingTime(" "); // 预约时间
        // 加急标志
        String urgencyFlag = ConstantsABC.ABC_ERP_URGENCYFLAG_FALSE;
        if ("0".equals(message.getEmergency()+"")) {
            urgencyFlag = ConstantsABC.ABC_ERP_URGENCYFLAG_TRUE;
        }
        corp.setUrgencyFlag(urgencyFlag);
        // 它行标志
        String othBankFlag = ConstantsABC.ABC_ERP_OTHBANKFLAG_FALSE;
        if ("1".equals(message.getSysIOFlg()+"")) {
            othBankFlag = ConstantsABC.ABC_ERP_OTHBANKFLAG_TRUE;
        }
        corp.setOthBankFlag(othBankFlag);
        corp.setCrAccName(message.getRecvBankAcctName());
        corp.setDbAccName(abcConfig.get("ABC.BCDL.PAY.ACCOUNTNAME"));
        corp.setWhyUse(abcConfig.get("ABC.BCDL.PAY.PERSON.WHYUSE"));
        //corp.setPostscript(abcConfig.get("ABC.BCDL.PAY.PERSON.POSTSCRIPT"));
        corp.setPostscript(message.getGopayBankOrderNo());

        ap.setCmp(cmp);
        ap.setCorp(corp);

        return ap;
    }

    /**
     * 构建对公对象
     * 
     * @param message
     * @return
     */
    private ApCorpReq convertCorp(BcdlMessage message) {
        ApCorpReq ap = new ApCorpReq();
        CmpCorpReq cmp = new CmpCorpReq();
        CorpReq corp = new CorpReq();
        ap.setBank(message.getBank());
        String transTime =TransUtil.getTransTime();
        Date orderDate = DateUtils.strToDate(transTime);

        ap.setTransCode(abcConfig.get("ABC.BCDL.CORP.TRANSCODE"));
        ap.setProductId(abcConfig.get("ABC.BCDL.PRODUCTID"));
        ap.setChannelType(abcConfig.get("ABC.BCDL.CHANNELTYPE"));
        ap.setCorpNo(abcConfig.get("ABC.BCDL.CORPNO"));
        ap.setOpNo(abcConfig.get("ABC.BCDL.OPNO"));
        ap.setAuthNo(" "); // 认证码
        ap.setReqSeqNo(message.getGopayBankOrderNo());
        ap.setReqDate(DateUtils.format(orderDate, "yyyyMMdd"));
        ap.setReqTime(DateUtils.format(orderDate, "HHmmss"));
        ap.setSign(" "); // 数字签名
        ap.setAmt(message.getAmount().toString());

        cmp.setDbProv(abcConfig.get("ABC.BCDL.PAY.ACCOUNTPROV"));
        cmp.setDbAccNo(abcConfig.get("ABC.BCDL.PAY.ACCOUNTNO"));
        cmp.setDbLogAccNo(" ");// 借方逻辑帐号
        cmp.setDbCur(ConstantsABC.ABC_ERP_CURTYPE_RMB);
        cmp.setCrProv(message.getRecvBankProvNo());
        cmp.setCrLogAccNo(" "); // 贷方逻辑账号
        cmp.setCrCur(ConstantsABC.ABC_ERP_CURTYPE_RMB);
        cmp.setConFlag(ConstantsABC.ABC_ERP_CONFLAG_TRUE);
        // 贷方账号
        String crAccNo = message.getRecvBankAcctNum();
        if (BankConstants.DCBL_CORP == message.getDcblType()) {
            crAccNo = getRecBankAcctNum(message.getRecvBankAcctNum());
        }
        cmp.setCrAccNo(crAccNo);

        corp.setPsFlag(" ");
        corp.setBookingFlag(ConstantsABC.ABC_ERP_BOOKINGFLAG_FALSE);
        corp.setBookingDate(" "); // 预约日期
        corp.setBookingTime(" "); // 预约时间
        // 加急标志
        String urgencyFlag = ConstantsABC.ABC_ERP_URGENCYFLAG_FALSE;
        if (message.getEmergency()==1) {
            urgencyFlag = ConstantsABC.ABC_ERP_URGENCYFLAG_TRUE;
        }
        corp.setUrgencyFlag(urgencyFlag);
        // 它行标志
        String othBankFlag = ConstantsABC.ABC_ERP_OTHBANKFLAG_FALSE;
        if (1== message.getSysIOFlg()) {
            othBankFlag = ConstantsABC.ABC_ERP_OTHBANKFLAG_TRUE;
        }
        corp.setOthBankFlag(othBankFlag);
        corp.setCrBankType(" "); // 它行行别
        corp.setCrAccName(message.getRecvBankAcctName());
        corp.setCrBankName(message.getPbocBankBranchName()); // 收款方开户行名
        corp.setCrBankNo(message.getPbocBankBranchCode());
        corp.setDbAccName(abcConfig.get("ABC.BCDL.PAY.ACCOUNTNAME"));
        corp.setWhyUse(abcConfig.get("ABC.BCDL.PAY.WHYUSE"));
        //corp.setPostscript(abcConfig.get("ABC.BCDL.PAY.POSTSCRIPT"));
        corp.setPostscript(message.getGopayBankOrderNo());

        ap.setCmp(cmp);
        ap.setCorp(corp);

        return ap;
    }

    /**
     * 当参数值是empty时返回空格
     */
    public String getSpaceIfEmpty(String value) {
        return StringUtils.isEmpty(value) ? " " : value;
    }

    /**
     * 农行对公银企直连账号是十七位，但是前两位是省市代码，后边的15位才是收款的账号 因此截取一下
     */
    private String getRecBankAcctNum(String accNum) {
        String bankAccNum = "";
        if (accNum.length() < 17) {
            // 15位
            bankAccNum = accNum;
        } else {
            // 17位截取为15位
            bankAccNum = accNum.substring(2, accNum.length());
        }
        return bankAccNum;
    }

    /**
     * 农行对账明细查询
     *
     * @return
     */
    public ApResCQRA10 queryAcctDetail(BcdlMessage message)  throws GopayException{
        // 构建查询对象
        ApReqCQRA10 ap = convertQueryApReqCQRA10(message);
        // 发送银行
        ApResCQRA10 res = (ApResCQRA10) abcBcdlService.queryAcctDetail(ap);
        return res;
    }

    /**
     * 构建查询账户明细 (CQRA10交易)
     *
     * @param message
     * @return
     */
    private ApReqCQRA10 convertQueryApReqCQRA10(BcdlMessage message) {
        ApReqCQRA10 ap10=new ApReqCQRA10();

        String transTime =TransUtil.getTransTime();
        Date orderDate = DateUtils.strToDate(transTime);

        ap10.setCctranscode("CQRA10");
        ap10.setTransCode("CQRA10");
        ap10.setProductId(abcConfig.get("ABC.BCDL.PRODUCTID"));
        ap10.setChannelType(abcConfig.get("ABC.BCDL.CHANNELTYPE"));
        ap10.setCorpNo(abcConfig.get("ABC.BCDL.CORPNO"));
        ap10.setOpNo(abcConfig.get("ABC.BCDL.OPNO"));
        ap10.setAuthNo(" "); // 认证码
//        ap10.setReqSeqNo(message.getGopayBankOrderNo());
        ap10.setReqSeqNo(transTime);
        ap10.setReqDate(DateUtils.format(orderDate, "yyyyMMdd"));
        ap10.setReqTime(DateUtils.format(orderDate, "HHmmss"));
        ap10.setSign(" "); // 数字签名

        CorpReqAp corpReq=new CorpReqAp();

        corpReq.setStartdate(message.getOrderDate());
        corpReq.setEnddate(message.getOrderDate());
        ap10.setCorpreq(corpReq);
        ChannelReq channelreq=new ChannelReq();
        channelreq.setLastjrnno("0");
        ap10.setChannelreq(channelreq);
//         CmpReq
        CmpReq cmpreq=new CmpReq();
        //借方账号
        cmpreq.setDbaccno(abcConfig.get("ABC.BCDL.PAY.ACCOUNTNO"));
        //借方省市代码
        cmpreq.setDbprov(abcConfig.get("ABC.BCDL.PAY.ACCOUNTPROV"));
        //借方货币号
        cmpreq.setDbcur(ConstantsABC.ABC_ERP_CURTYPE_RMB);
        //末笔时间戳
        cmpreq.setStarttime("");
        ap10.setCmpreq(cmpreq);

        return ap10;
    }
}
